home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 44 / PC Actual CD 44.iso / Linux / Cygwin / full.exe / Disk1 / data1.cab / Tools / share / dejagnu / config / gdb-comm.exp < prev    next >
Encoding:
Text File  |  1998-12-04  |  15.1 KB  |  539 lines

  1. # Copyright (C) 1996, 1997 Free Software Foundation, Inc.
  2.  
  3. # This program is free software; you can redistribute it and/or modify
  4. # it under the terms of the GNU General Public License as published by
  5. # the Free Software Foundation; either version 2 of the License, or
  6. # (at your option) any later version.
  7. # This program is distributed in the hope that it will be useful,
  8. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10. # GNU General Public License for more details.
  11. # You should have received a copy of the GNU General Public License
  12. # along with this program; if not, write to the Free Software
  13. # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14.  
  15. # Please email any bugs, comments, and/or additions to this file to:
  16. # DejaGnu@cygnus.com
  17.  
  18. # Note: some of this was cribbed from the gdb testsuite since we need
  19. # to use some pretty standard gdb features (breakpoints in particular).
  20.  
  21. # Load up some standard junk.
  22. load_lib remote.exp
  23.  
  24. if ![info exists board] {
  25.     perror "$board must be set before loading gdb-comm"
  26. }
  27.  
  28. # The number of times we've tried to download/execute this executable.
  29. set try_again 0
  30.  
  31. #
  32. # Delete all breakpoints and verify that they were deleted.  If anything
  33. # goes wrong, return -1.
  34. #
  35. proc gdb_comm_delete_breakpoints {} {
  36.     global gdb_prompt
  37.  
  38.     remote_send host "delete breakpoints\n";
  39.     remote_expect host 10 {
  40.     -re "Delete all breakpoints.*y or n. $" {
  41.         remote_send host "y\n"
  42.         exp_continue
  43.     }
  44.     -re ".*$gdb_prompt $" { }
  45.     timeout { perror "Delete all breakpoints (timeout)" ; return -1}
  46.     }
  47.     remote_send host "info breakpoints\n"
  48.     remote_expect host 10 {
  49.     -re "No breakpoints or watchpoints..*$gdb_prompt $" {}
  50.     -re ".*$gdb_prompt $" { perror "breakpoints not deleted" ; return -1}
  51.     timeout { perror "info breakpoints (timeout)" ; return -1}
  52.     }
  53.     return 0;
  54. }
  55.  
  56. #
  57. # Inform the debugger that we have a new exec file.
  58. # return a -1 if anything goes wrong, 0 on success.
  59. #
  60. proc gdb_comm_file_cmd { arg } {
  61.     global verbose
  62.     global loadpath
  63.     global loadfile
  64.     global GDB
  65.     global gdb_prompt
  66.     upvar timeout timeout
  67.  
  68.     # The "file" command loads up a new symbol file for gdb, deal with
  69.     # the various messages it might spew out.
  70.     if [is_remote host] {
  71.     set arg [remote_download host $arg a.out];
  72.     }
  73.     remote_send host "file $arg\n"
  74.     remote_expect host 60 {
  75.         -re "Reading symbols from.*done.*$gdb_prompt $" {
  76.             verbose "\t\tLoaded $arg into the $GDB"
  77.             return 0
  78.         }
  79.         -re "has no symbol-table.*$gdb_prompt $" {
  80.             perror "$arg wasn't compiled with \"-g\""
  81.             return -1
  82.         }
  83.         -re "A program is being debugged already.*Kill it.*y or n. $" {
  84.             remote_send host "y\n"
  85.         verbose "\t\tKilling previous program being debugged"
  86.             exp_continue
  87.         }
  88.         -re "Load new symbol table from \".*\".*y or n.*$" {
  89.             remote_send host "y\n"
  90.             remote_expect host 60 {
  91.                 -re "Reading symbols from.*done.*$gdb_prompt $" {
  92.                     verbose "\t\tLoaded $arg with new symbol table into $GDB"
  93.                     return 0
  94.                 }
  95.                 timeout {
  96.                     perror "(timeout) Couldn't load $arg, other program already loaded."
  97.                     return -1
  98.                 }
  99.             }
  100.     }
  101.         -re ".*No such file or directory.*$gdb_prompt $" {
  102.             perror "($arg) No such file or directory\n"
  103.             return -1
  104.         }
  105.         -re "$gdb_prompt $" {
  106.             perror "couldn't load $arg into $GDB."
  107.             return -1
  108.             }
  109.         timeout {
  110.             perror "couldn't load $arg into $GDB (timed out)."
  111.             return -1
  112.         }
  113.     eof {
  114.             # This is an attempt to detect a core dump, but seems not to
  115.             # work.  Perhaps we need to match .* followed by eof, in which
  116.             # expect does not seem to have a way to do that.
  117.             perror "couldn't load $arg into $GDB (end of file)."
  118.             return -1
  119.         }
  120.     }
  121.     return 0;
  122. }
  123.  
  124. # Disconnect from the target and forget that we have an executable. Returns
  125. # -1 on failure, 0 on success.
  126.  
  127. proc gdb_comm_go_idle { } {
  128.     global gdb_prompt;
  129.  
  130.     if ![board_info host exists fileid] {
  131.     return -1;
  132.     }
  133.  
  134.     remote_send host "target exec\n";
  135.     remote_expect host 10 {
  136.     -re "Kill it.*y or n.*$" {
  137.         remote_send host "y\n"
  138.         exp_continue;
  139.     }
  140.     -re "No exec file now.*$gdb_prompt $" { 
  141.         return 0;
  142.     }
  143.     default {
  144.         remote_close host;
  145.         return -1;
  146.     }
  147.     }
  148. }
  149.  
  150. # Start GDB running with target DEST.
  151. proc gdb_comm_start { dest } {
  152.     global GDB
  153.     global gdb_prompt
  154.     global tool_root_dir
  155.  
  156.     # The variable gdb_prompt is a regexp which matches the gdb prompt.  Set it
  157.     # if it is not already set.
  158.     if ![board_info $dest exists gdb_prompt] then {
  159.     set gdb_prompt "\\(gdb\\)"
  160.     } else {
  161.     set gdb_prompt [board_info $dest gdb_prompt];
  162.     }
  163.     # Similarly for GDB.  Look in the object directory for gdb if we aren't
  164.     # provided with one.
  165.     if ![info exists GDB] then {
  166.     set GDB "[lookfor_file ${tool_root_dir} gdb/gdb]"
  167.     if { $GDB == "" } {
  168.         set GDB [transform gdb]
  169.     }
  170.     }
  171.     if [board_info host exists gdb_opts] {
  172.     set gdb_opts [board_info host gdb_opts];
  173.     } else {
  174.     set gdb_opts ""
  175.     }
  176.     # Start up gdb (no startfiles, no windows) and wait for a prompt.
  177.     remote_spawn host "$GDB $gdb_opts -nw -nx";
  178.     remote_expect host 60 {
  179.     -re ".*$gdb_prompt $" { }
  180.     }
  181.     remote_send host "set height 0\n";
  182.     remote_expect host 10 {
  183.     -re ".*$gdb_prompt $" {}
  184.     }
  185.     remote_send host "set width 0\n";
  186.     remote_expect host 10 {
  187.     -re ".*$gdb_prompt $" {}
  188.     }
  189. }
  190.  
  191. # Add a breakpoint at function FUNCTION. We assume that GDB has already been
  192. # started.
  193. proc gdb_comm_add_breakpoint { function } {
  194.     global gdb_prompt
  195.  
  196.     remote_send host "break $function\n"
  197.     remote_expect host 60 {
  198.     -re "Breakpoint.*$gdb_prompt $" { return "" }
  199.     -re "Function.*not defined.*$gdb_prompt $" { return "undef" }
  200.     -re "No symbol table.*$gdb_prompt $" { return "undef" }
  201.     default {
  202.         return "untested"
  203.     }
  204.     }
  205. }
  206.  
  207. #
  208. # quit_gdb -- try to quit GDB gracefully
  209. #
  210.  
  211. proc quit_gdb { } {
  212.     global gdb_prompt;
  213.  
  214.     set spawn_id [board_info host fileid];
  215.  
  216.     if { $spawn_id != "" && $spawn_id > -1 } {
  217.     if { [remote_send host "quit\n"] == "" } {
  218.         remote_expect host 10 {
  219.         -re ".*y or n.*$" {
  220.             remote_send host "y\n";
  221.             exp_continue;
  222.         }
  223.         -re ".*\[*\]\[*\]\[*\].*EXIT code" { }
  224.         default { }
  225.         }
  226.     }
  227.     }
  228.     remote_close host;
  229. }
  230.  
  231. proc gdb_comm_leave { } {
  232.     if [is_remote host] {
  233.     quit_gdb;
  234.     } else {
  235.     gdb_comm_go_idle;
  236.     }
  237. }
  238. #
  239. # gdb_comm_load -- load the program and execute it
  240. #
  241. # PROG is a full pathname to the file to load, no arguments.
  242. # Result is "untested", "pass", "fail", etc.
  243. #
  244.  
  245. proc gdb_comm_load { dest prog args } {
  246.     global GDB
  247.     global GDBFLAGS
  248.     global gdb_prompt
  249.     global timeout
  250.     set argnames { "command-line arguments" "input file" "output file" }
  251.  
  252.     for { set x 0; } { $x < [llength $args] } { incr x } {
  253.     if { [lindex $args $x] != "" } {
  254.         return [list "unsupported" "no support for [lindex $argnames $x] on this target"];
  255.     }
  256.     }
  257.     # Make sure the file we're supposed to load really exists.
  258.     if ![file exists $prog] then {
  259.     perror "$prog does not exist."
  260.         return [list "untested" ""];
  261.     }
  262.  
  263.     if { [is_remote host] || ![board_info host exists fileid] } {
  264.     gdb_comm_start $dest;
  265.     }
  266.  
  267.     # Remove all breakpoints, then tell the debugger that we have
  268.     # new exec file.
  269.     if { [gdb_comm_delete_breakpoints] != 0 } {
  270.     gdb_comm_leave;
  271.     return [gdb_comm_reload $dest $prog $args];
  272.     }
  273.     if { [gdb_comm_file_cmd $prog] != 0 } {
  274.     gdb_comm_leave;
  275.     return [gdb_comm_reload $dest $prog $args];
  276.     }
  277.     if [board_info $dest exists gdb_sect_offset] {
  278.     set textoff [board_info $dest gdb_sect_offset];
  279.     remote_send host "sect .text $textoff\n";
  280.     remote_expect host 10 {
  281.         -re "(0x\[0-9a-z]+) - 0x\[0-9a-z\]+ is \\.data" {
  282.         set dataoff $expect_out(1,string);
  283.         exp_continue;
  284.         }
  285.         -re "(0x\[0-9a-z\]+) - 0x\[0-9a-z\]+ is \\.bss" {
  286.         set bssoff $expect_out(1,string);
  287.         exp_continue;
  288.         }
  289.         -re "$gdb_prompt" { }
  290.     }
  291.     set dataoff [format 0x%x [expr $dataoff + $textoff]];
  292.     set bssoff [format 0x%x [expr $bssoff + $textoff]];
  293.     remote_send host "sect .data $dataoff\n";
  294.     remote_expect host 10 {
  295.         -re "$gdb_prompt" { }
  296.     }
  297.     remote_send host "sect .bss $bssoff\n";
  298.     remote_expect host 10 {
  299.         -re "$gdb_prompt" { }
  300.     }
  301.     }
  302.  
  303.     # Now set up breakpoints in exit, _exit, and abort.  These
  304.     # are used to determine if a c-torture test passed or failed.  More
  305.     # work would be necessary for things like the g++ testsuite which
  306.     # use printf to indicate pass/fail status.
  307.  
  308.     if { [gdb_comm_add_breakpoint _exit] != "" } {
  309.     gdb_comm_add_breakpoint exit;
  310.     }
  311.     gdb_comm_add_breakpoint abort;
  312.  
  313.     set protocol [board_info $dest gdb_protocol];
  314.     if [board_info $dest exists gdb_serial] {
  315.     set targetname [board_info $dest gdb_serial];
  316.     } elseif [board_info $dest exists netport] {
  317.     set targetname [board_info $dest netport];
  318.     } else {
  319.     if [board_info $dest exists serial] {
  320.         set targetname [board_info $dest serial];
  321.     } else {
  322.         set targetname ""
  323.     }
  324.     }
  325.     if [board_info $dest exists baud] {
  326.     remote_send host "set remotebaud [board_info $dest baud]\n"
  327.     remote_expect host 10 {
  328.         -re ".*$gdb_prompt $" {}
  329.         default {
  330.         warning "failed setting baud rate";
  331.         }
  332.     }
  333.     }
  334.     remote_send host "target $protocol $targetname\n";
  335.     remote_expect host 60 {
  336.     -re "Couldn.t establish conn.*$gdb_prompt $" {
  337.         warning "Unable to connect to $targetname with GDB."
  338.         quit_gdb;
  339.         return [gdb_comm_reload $dest $prog $args]
  340.     }
  341.     -re "Ending remote.*$gdb_prompt $" {
  342.         warning "Unable to connect to $targetname with GDB."
  343.         quit_gdb;
  344.         return [gdb_comm_reload $dest $prog $args]
  345.     }
  346.     -re "Remote target $protocol connected to.*$gdb_prompt $" { }
  347.     -re "Remote target $targetname connected to.*$gdb_prompt $" { }
  348.     -re "Connected to ARM RDI target.*$gdb_prompt $" { }
  349.     -re "Connected to the simulator.*$gdb_prompt $" { }
  350.     -re "Remote.*using $targetname.*$gdb_prompt $" { }
  351.     -re "$gdb_prompt $" {
  352.         warning "Unable to connect to $targetname with GDB."
  353.         quit_gdb;
  354.         return [gdb_comm_reload $dest $prog $args]
  355.     }
  356.     -re ".*RDI_open.*should reset target.*" {
  357.         warning "RDI Open Failed"
  358.         quit_gdb;
  359.         return [gdb_comm_reload $dest $prog $args]
  360.     }
  361.     default {
  362.         warning "Unable to connect to $targetname with GDB."
  363.         quit_gdb;
  364.         return [gdb_comm_reload $dest $prog $args]
  365.     }
  366.     }
  367.  
  368.     if [target_info exists gdb_init_command] {
  369.     remote_send host "[target_info gdb_init_command]\n";
  370.     remote_expect host 10 {
  371.         -re ".*$gdb_prompt $" { }
  372.         default {
  373.         gdb_comm_leave;
  374.         return [list "fail" ""];
  375.         }
  376.     }
  377.     }
  378.     # Now download the executable to the target board.  If communications
  379.     # with the target are very slow the timeout might need to be increased.
  380.     if [board_info $dest exists gdb_load_offset] {
  381.     remote_send host "load $prog [board_info $dest gdb_load_offset]\n";
  382.     } else {
  383.     remote_send host "load\n"
  384.     }
  385.     remote_expect host 600 {
  386.     -re "text.*data.*$gdb_prompt $" { }
  387.     -re "data.*text.*$gdb_prompt $" { }
  388.     -re "$gdb_prompt $" {
  389.         warning "Unable to send program to target board."
  390.         gdb_comm_leave;
  391.         return [gdb_comm_reload $dest $prog $args];
  392.     }
  393.     default {
  394.         warning "Unable to send program to target board."
  395.         gdb_comm_leave;
  396.         return [gdb_comm_reload $dest $prog $args];
  397.     }
  398.     }
  399.  
  400.     set output ""
  401.     
  402.     # Now start up the program and look for our magic breakpoints.
  403.     # And a whole lot of other magic stuff too.
  404.  
  405.     if [board_info $dest exists gdb_run_command] {
  406.     remote_send host "[board_info $dest gdb_run_command]\n";
  407.     } else {
  408.     remote_send host "run\n"
  409.     }
  410.     # FIXME: The value 300 below should be a parameter.
  411.     if [board_info $dest exists testcase_timeout] {
  412.     set testcase_timeout [board_info $dest testcase_timeout];
  413.     } else {
  414.     set testcase_timeout 300;
  415.     }
  416.     remote_expect host $testcase_timeout {
  417.     -re "Line.*Jump anyway.*.y or n.*" {
  418.         remote_send host "y\n";
  419.         exp_continue;
  420.     }
  421.     -re "Continuing( at |\\.| with no signal\\.)\[^\r\n\]*\[\r\n\]" {
  422.         exp_continue;
  423.     }
  424.     -re ".*Start it from the beginning?.*y or n.*" {
  425.         remote_send host "n\n";
  426.         remote_expect host 10 {
  427.         -re ".*$gdb_prompt $" {
  428.             remote_send host "signal 0\n";
  429.             remote_expect host 10 {
  430.             -re "signal 0\[\r\n\]+" { exp_continue; }
  431.             -re "Continuing(\\.| with no signal\\.)\[\r\n\]" {}
  432.             }
  433.         }
  434.         }
  435.         exp_continue
  436.     }
  437.     -re "(run\[\r\n\]*|)Starting program: \[^\r\n\]*\[\r\n\]" {
  438.         exp_continue
  439.     }
  440.     -re "$gdb_prompt (signal 0|continue)\[\r\n\]+Continuing(\\.| with no signal\\.)\[\r\n\]" {
  441.         exp_continue
  442.     }
  443.     -re "(.*)Breakpoint.*exit.*=0.*$gdb_prompt $" {
  444.         append output $expect_out(1,string);
  445.         set result [check_for_board_status output];
  446.         gdb_comm_leave;
  447.         if { $result > 0 } {
  448.         return [list "fail" $output];
  449.         }
  450.         return [list "pass" $output];
  451.     }
  452.     -re "(.*)Breakpoint.*exit.*=\[1-9\]\[0-9\]*.*$gdb_prompt $" {
  453.         append output $expect_out(1,string);
  454.         set result [check_for_board_status output];
  455.         gdb_comm_leave;
  456.         if { $result == 0 } {
  457.         return [list "pass" $output];
  458.         }
  459.         if [board_info $dest exists exit_statuses_bad] {
  460.         return [list "pass" $output];
  461.         }
  462.         return [list "fail" $output];
  463.     }
  464.     -re "(.*)Breakpoint.*exit.*$gdb_prompt $" {
  465.         append output $expect_out(1,string);
  466.         set status [check_for_board_status output];
  467.         gdb_comm_leave;
  468.         if { $status > 0 } {
  469.         return [list "fail" $output];
  470.         }
  471.         return [list "pass" $output];
  472.     }
  473.     -re "(.*)Breakpoint.*abort.*$gdb_prompt $" {
  474.         append output $expect_out(1,string);
  475.         check_for_board_status output;
  476.         gdb_comm_leave;
  477.         return [list "fail" $output];
  478.     }
  479.     -re "SIGTRAP.*$gdb_prompt $" {
  480.         return [gdb_comm_reload $dest $prog $args];
  481.     }
  482.     -re "(.*)Program (received |terminated ).*$gdb_prompt $" {
  483.         set output $expect_out(1,string);
  484.         check_for_board_status output;
  485.         gdb_comm_leave;
  486.         remote_reboot $dest;
  487.         return [list "fail" $output];
  488.     }
  489.     -re "(.*)Program exited with code \[0-9\]+.*$gdb_prompt $" {
  490.         set output $expect_out(1,string);
  491.         set status [check_for_board_status output];
  492.         gdb_comm_leave;
  493.         if { $status > 0 } {
  494.         return [list "fail" $output];
  495.         }
  496.         return [list "pass" $output];
  497.     }
  498.     default {
  499.         gdb_comm_leave;
  500.         if [board_info $dest exists unreliable] {
  501.         if { [board_info $dest unreliable] > 0 } {
  502.             global board_info;
  503.             set name [board_info $dest name];
  504.             incr board_info($name,unreliable) -1;
  505.             set result [gdb_comm_reload $dest $prog $args];
  506.             incr board_info($name,unreliable);
  507.             return $result;
  508.         }
  509.         }
  510.         return [list "fail" ""];
  511.     }
  512.     }
  513.     gdb_comm_leave;
  514.     return [list "fail" ""];
  515. }
  516.  
  517. # If we've tried less than 4 times to load PROG, reboot the target, restart GDB
  518. # and try again. Otherwise, return "untested".
  519. proc gdb_comm_reload { dest prog aargs } {
  520.     global try_again;
  521.  
  522.     if { $try_again < 4 } {
  523.     global GDB;
  524.     remote_reboot $dest;
  525.     remote_close host;
  526.     incr try_again;
  527.     set result [eval remote_load \"$dest\" \"$prog\" $aargs]
  528.     set try_again 0;
  529.     return "$result";
  530.     } else {
  531.     set try_again 0;
  532.     return [list "untested" ""];
  533.     }
  534. }
  535.  
  536. set_board_info protocol  "gdb_comm";
  537.